<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
  <title>Description of v_rotro2eu</title>
  <meta name="keywords" content="v_rotro2eu">
  <meta name="description" content="V_ROTRO2EU converts a 3x3 rotation matrix into the corresponding euler angles">
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta name="generator" content="m2html &copy; 2003 Guillaume Flandin">
  <meta name="robots" content="index, follow">
  <link type="text/css" rel="stylesheet" href="../m2html.css">
</head>
<body>
<a name="_top"></a>
<div><a href="../index.html">Home</a> &gt;  <a href="index.html">v_mfiles</a> &gt; v_rotro2eu.m</div>

<!--<table width="100%"><tr><td align="left"><a href="../index.html"><img alt="<" border="0" src="../left.png">&nbsp;Master index</a></td>
<td align="right"><a href="index.html">Index for v_mfiles&nbsp;<img alt=">" border="0" src="../right.png"></a></td></tr></table>-->

<h1>v_rotro2eu
</h1>

<h2><a name="_name"></a>PURPOSE <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="box"><strong>V_ROTRO2EU converts a 3x3 rotation matrix into the corresponding euler angles</strong></div>

<h2><a name="_synopsis"></a>SYNOPSIS <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="box"><strong>function e=v_rotro2eu(m,r) </strong></div>

<h2><a name="_description"></a>DESCRIPTION <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="fragment"><pre class="comment">V_ROTRO2EU converts a 3x3 rotation matrix into the corresponding euler angles
 inverse of v_roteu2ro
     M        a string of n characters from the set determining the order of rotation axes
              as listed below. Note that the control characters 'rdoOaA' may occur anywhere in the string:
                'x','y','z'    rotate around the given axis by the corresponding angle
                               given in e()
                '1','2','3'    90 degree rotation around x,y or z axis; doesn't use a value from e()
                '4','5','6'    180 degree rotation around x,y or z axis; doesn't use a value from e()
                '7','8','9'    270 degree rotation around x,y or z axis; doesn't use a value from e()
                'r','d'        all angles are given in radians or degrees  [default='r']
                'R','D'        all angles are given in radians or degrees and are negated
             'o','O','a','A'   selects whether to rotate the object or the coordinate axes and
                               whether the rotation axes remain fixed in space for consecutive
                               rotations (extrinsic) or else move with each rotation (intrinsic).
                                  'o' = object-extrinsic [default]
                                  'O' = object-intrinsic
                                  'a' = axes-extrinsic
                                  'A' = axes-intrinsic

     R(3,3,...)   Input rotation matrix (or array of matrices)

 Outputs:

     E(K,...)  K Euler angles in radians (or degrees if 'd' or 'D' specified) per quaternion where K is the number of 'xyz' characters in M.
               A positive rotation is clockwise if looking along the +ve axis away from the origin or anti-clockwise if 'R' or 'D' is given.
               The x, y, z axes form a right-handed triple.

 The string M specifies the seqeunce of axes about which the rotations are performed. There are 12
 possible 3-character sequences that avoid consecutive repetitions. These are 'Euler angles' if
 there is a repeated axis or 'Tait-Bryan angles' if not. Common choices are:
 (1) 'zxz' the most common Euler angle set
 (2) 'xyz' corresponds to 'roll, pitch, yaw' for an aeroplane heading in the x direction with y to
     the right and z down. The intrinsic equivalent is 'Ozyx' corresponding to 'yaw, pitch, roll'.
 (3) 'z1z1z' involves 5 rotations, in which all the non-fixed rotations are around the z axis.

 The Euler angles are not, in general, unique. In particular:
  (1) v_roteu2ro('zxz',[a b c]) = v_roteu2ro('zxz',[a+pi -b c+pi])
  (2) v_roteu2ro('xyz',[a b c]) = v_roteu2ro('xyz',[a+pi pi-b c+pi])</pre></div>

<!-- crossreference -->
<h2><a name="_cross"></a>CROSS-REFERENCE INFORMATION <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
This function calls:
<ul style="list-style-image:url(../matlabicon.gif)">
<li><a href="v_atan2sc.html" class="code" title="function [s,c,r,t]=v_atan2sc(y,x)">v_atan2sc</a>	V_ATAN2SC    sin and cosine of atan(y/x) [S,C,R,T]=(Y,X)</li><li><a href="v_roteucode.html" class="code" title="function mv=v_roteucode(m)">v_roteucode</a>	V_ROTEUCODE decodes a string specifying a rotation axis sequence</li><li><a href="v_rotro2qr.html" class="code" title="function q=v_rotro2qr(r)">v_rotro2qr</a>	V_ROTRO2QR converts a 3x3 rotation matrix to a real quaternion</li></ul>
This function is called by:
<ul style="list-style-image:url(../matlabicon.gif)">
<li><a href="v_rectifyhomog.html" class="code" title="function [imr,xa,ya]=v_rectifyhomog(ims,roc,k0,mode)">v_rectifyhomog</a>	V_RECTIFYHOMOG Apply rectifying homographies to an image set</li><li><a href="v_rotqr2eu.html" class="code" title="function e=v_rotqr2eu(m,q)">v_rotqr2eu</a>	V_ROTQR2EQ converts a real unit quaternion into the corresponding euler angles</li></ul>
<!-- crossreference -->


<h2><a name="_source"></a>SOURCE CODE <a href="#_top"><img alt="^" border="0" src="../up.png"></a></h2>
<div class="fragment"><pre>0001 <a name="_sub0" href="#_subfunctions" class="code">function e=v_rotro2eu(m,r)</a>
0002 <span class="comment">%V_ROTRO2EU converts a 3x3 rotation matrix into the corresponding euler angles</span>
0003 <span class="comment">% inverse of v_roteu2ro</span>
0004 <span class="comment">%     M        a string of n characters from the set determining the order of rotation axes</span>
0005 <span class="comment">%              as listed below. Note that the control characters 'rdoOaA' may occur anywhere in the string:</span>
0006 <span class="comment">%                'x','y','z'    rotate around the given axis by the corresponding angle</span>
0007 <span class="comment">%                               given in e()</span>
0008 <span class="comment">%                '1','2','3'    90 degree rotation around x,y or z axis; doesn't use a value from e()</span>
0009 <span class="comment">%                '4','5','6'    180 degree rotation around x,y or z axis; doesn't use a value from e()</span>
0010 <span class="comment">%                '7','8','9'    270 degree rotation around x,y or z axis; doesn't use a value from e()</span>
0011 <span class="comment">%                'r','d'        all angles are given in radians or degrees  [default='r']</span>
0012 <span class="comment">%                'R','D'        all angles are given in radians or degrees and are negated</span>
0013 <span class="comment">%             'o','O','a','A'   selects whether to rotate the object or the coordinate axes and</span>
0014 <span class="comment">%                               whether the rotation axes remain fixed in space for consecutive</span>
0015 <span class="comment">%                               rotations (extrinsic) or else move with each rotation (intrinsic).</span>
0016 <span class="comment">%                                  'o' = object-extrinsic [default]</span>
0017 <span class="comment">%                                  'O' = object-intrinsic</span>
0018 <span class="comment">%                                  'a' = axes-extrinsic</span>
0019 <span class="comment">%                                  'A' = axes-intrinsic</span>
0020 <span class="comment">%</span>
0021 <span class="comment">%     R(3,3,...)   Input rotation matrix (or array of matrices)</span>
0022 <span class="comment">%</span>
0023 <span class="comment">% Outputs:</span>
0024 <span class="comment">%</span>
0025 <span class="comment">%     E(K,...)  K Euler angles in radians (or degrees if 'd' or 'D' specified) per quaternion where K is the number of 'xyz' characters in M.</span>
0026 <span class="comment">%               A positive rotation is clockwise if looking along the +ve axis away from the origin or anti-clockwise if 'R' or 'D' is given.</span>
0027 <span class="comment">%               The x, y, z axes form a right-handed triple.</span>
0028 <span class="comment">%</span>
0029 <span class="comment">% The string M specifies the seqeunce of axes about which the rotations are performed. There are 12</span>
0030 <span class="comment">% possible 3-character sequences that avoid consecutive repetitions. These are 'Euler angles' if</span>
0031 <span class="comment">% there is a repeated axis or 'Tait-Bryan angles' if not. Common choices are:</span>
0032 <span class="comment">% (1) 'zxz' the most common Euler angle set</span>
0033 <span class="comment">% (2) 'xyz' corresponds to 'roll, pitch, yaw' for an aeroplane heading in the x direction with y to</span>
0034 <span class="comment">%     the right and z down. The intrinsic equivalent is 'Ozyx' corresponding to 'yaw, pitch, roll'.</span>
0035 <span class="comment">% (3) 'z1z1z' involves 5 rotations, in which all the non-fixed rotations are around the z axis.</span>
0036 <span class="comment">%</span>
0037 <span class="comment">% The Euler angles are not, in general, unique. In particular:</span>
0038 <span class="comment">%  (1) v_roteu2ro('zxz',[a b c]) = v_roteu2ro('zxz',[a+pi -b c+pi])</span>
0039 <span class="comment">%  (2) v_roteu2ro('xyz',[a b c]) = v_roteu2ro('xyz',[a+pi pi-b c+pi])</span>
0040 
0041 <span class="comment">%      Copyright (C) Mike Brookes 2007-2020</span>
0042 <span class="comment">%      Version: $Id: v_rotro2eu.m 11260 2020-07-18 20:07:58Z dmb $</span>
0043 <span class="comment">%</span>
0044 <span class="comment">%   VOICEBOX is a MATLAB toolbox for speech processing.</span>
0045 <span class="comment">%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html</span>
0046 <span class="comment">%</span>
0047 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0048 <span class="comment">%   This program is free software; you can redistribute it and/or modify</span>
0049 <span class="comment">%   it under the terms of the GNU General Public License as published by</span>
0050 <span class="comment">%   the Free Software Foundation; either version 2 of the License, or</span>
0051 <span class="comment">%   (at your option) any later version.</span>
0052 <span class="comment">%</span>
0053 <span class="comment">%   This program is distributed in the hope that it will be useful,</span>
0054 <span class="comment">%   but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
0055 <span class="comment">%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
0056 <span class="comment">%   GNU General Public License for more details.</span>
0057 <span class="comment">%</span>
0058 <span class="comment">%   You can obtain a copy of the GNU General Public License from</span>
0059 <span class="comment">%   http://www.gnu.org/copyleft/gpl.html or by writing to</span>
0060 <span class="comment">%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.</span>
0061 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0062 <span class="keyword">persistent</span> mch mvch rtr rtci rtsi scai w6 th6 x6 pmw
0063 <span class="keyword">if</span> isempty(mvch)
0064     mch=<span class="string">''</span>; <span class="comment">% cached rotation code string</span>
0065     mvch=[0;0;1;1;0;0;1];
0066     rtr=[1 4 7 2 5 8 3 6 9]; <span class="comment">% indices to transpose a vectorized 3x3 matrix</span>
0067     rtci=[2 3 5 6 8 9; 3 1 6 4 9 7; 1 2 4 5 7 8]';
0068     rtsi=[3 2 6 5 9 8; 1 3 4 6 7 9; 2 1 5 4 8 7]';
0069     scai=[0 0 0 1; 0 0 0 2; 0 0 0 3; 1 -1 0 1; 1 -1 0 2; 1 -1 0 3; 0 0 -1 1; 0 0 -1 2; 0 0 -1 3; -1 1 0 1; -1 1 0 2; -1 1 0 3]'; <span class="comment">% [sin; -sin; cos; xyz] for fixed rotations</span>
0070     w6=ones(6,1); <span class="comment">%</span>
0071     th6=3*w6;
0072     x6=[2 1 2 1 2 1]'; <span class="comment">% Index for sin components</span>
0073     pmw=[1; -1];
0074 <span class="keyword">end</span>
0075 
0076 <span class="keyword">if</span> ~nargout
0077     <a href="v_rotro2qr.html" class="code" title="function q=v_rotro2qr(r)">v_rotro2qr</a>(r);
0078 <span class="keyword">else</span>
0079 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0080 <span class="comment">% Convert the m string</span>
0081 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0082     <span class="keyword">if</span> ischar(m) &amp;&amp; strcmp(m,mch) <span class="comment">% check if the rotation code string is cached</span>
0083         mv=mvch;
0084     <span class="keyword">else</span>
0085         mv=<a href="v_roteucode.html" class="code" title="function mv=v_roteucode(m)">v_roteucode</a>(m); <span class="comment">% else decode the string</span>
0086         mch=m; <span class="comment">% and save the result in the cache for next time.</span>
0087         mvch=mv;
0088     <span class="keyword">end</span>
0089 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0090 <span class="comment">% Now calculate euler angles</span>
0091 <span class="comment">%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%</span>
0092     nm=size(mv,2)-1; <span class="comment">% number of rotation codes</span>
0093     sz=size(r);
0094     r=reshape(r,9,[]); <span class="comment">% vectorize the rotation matrices</span>
0095     nr=size(r,2);                       <span class="comment">% number of rotation matrices</span>
0096     <span class="keyword">if</span> mv(end)&lt;0
0097         r=r(rtr,:);                     <span class="comment">% transpose rotation matrix</span>
0098     <span class="keyword">end</span>
0099     e=zeros(mv(2,end),nr);              <span class="comment">% initialize array of euler angles</span>
0100     ef=mv(end-3);
0101     <span class="keyword">for</span> i=nm:-1:1                       <span class="comment">% process rotations in reverse order</span>
0102         mvi=mv(:,i);
0103         mi=mvi(1);
0104         <span class="keyword">if</span> mi&lt;=3                        <span class="comment">% rotation around x,y or z</span>
0105             <span class="keyword">if</span> mvi(6)~=0               <span class="comment">% skip if this rotation is redundant</span>
0106                 [si,ci,ri,ti]=<a href="v_atan2sc.html" class="code" title="function [s,c,r,t]=v_atan2sc(y,x)">v_atan2sc</a>(mvi(7)*r(mvi(4),:),mvi(7)*r(mvi(5),:));
0107                 e(mv(2,i),:)=ti*mvi(6)/ef;  <span class="comment">% save the euler angle</span>
0108                 si=mvi(6)*pmw*si;          <span class="comment">% make -si available and correct sign</span>
0109                 r(rtci(:,mi),:)=ci(w6,:).*r(rtci(:,mi),:)-si(x6,:).*r(rtsi(:,mi),:); <span class="comment">% apply reverse rotation</span>
0110             <span class="keyword">end</span>
0111         <span class="keyword">else</span> <span class="comment">% fixed rotation</span>
0112             ai=scai(4,mi);                      <span class="comment">% axis of rotation: 1, 2 or 3</span>
0113             r(rtci(:,ai),:)=scai(th6,mi).*r(rtci(:,ai),:)-scai(x6,mi).*r(rtsi(:,ai),:); <span class="comment">% apply reverse rotation</span>
0114         <span class="keyword">end</span>
0115     <span class="keyword">end</span>
0116     <span class="keyword">if</span> nr&gt;1                                     <span class="comment">% if there was &gt;1 input matrix</span>
0117         e=reshape(e,[size(e,1) sz(3:end)]);     <span class="comment">% restore the shape of the Euler angle array</span>
0118     <span class="keyword">end</span>
0119 <span class="keyword">end</span></pre></div>
<hr><address>Generated by <strong><a href="http://www.artefact.tk/software/matlab/m2html/">m2html</a></strong> &copy; 2003</address>
</body>
</html>